package com.artup.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.artup.common.Constants;
import com.artup.common.ResponseResult;
import com.artup.dao.OrderDao;
import com.artup.pojo.Order;
import com.artup.service.PayService;

@Service( value = "payService" )
public class PayServiceImpl implements PayService {
	private static final Logger LOGGER = LoggerFactory.getLogger(PayServiceImpl.class);
	@Autowired
	private OrderDao orderDao;
	
	private final String PARTNER_ID = "2088612265937162";		// 合作者身份(PID)
	private final String SELLER_ID = "1421475485@qq.com";		// 签约卖家支付宝账号
//	private final String APP_ID = "2016080300155014";		// APP_ID
	private final String APP_ID = "2017040706577914";		// APP_ID
	private final String CHARSET = "UTF-8";		// APP_ID
	private final String APP_PRIVATE_KEY = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCnj6K+L1cvbxAAz6nykMn+A3V4Mimsj6k8TC5c3eiaGxv2TuSngf3koBW5RwZpAE51EnN1iifPpYQh81hg5ASLx3C45AWNkiZdcTbnZ+xIgUvYduimdoqL7UB8tpBjFqtK3LrAdbE2qpq6JfonAhJdSpF/QE8Tbrp6otnr3YB1snXllNOB0MOd1VD+chSZwYXapS+0seSpsFtqQ3tXzjm/tmLueafRrKzm1GFkjQrYK25KnhNgcNYMr5KDGKj6IMRVAjorpaGOd/N2+kqu0x0liijnYzoW3AP7Uj7Xq5/Yh0urSKFNE5S2C6qaFrgoejoGow2uWuum0LqHh2YmDb8FAgMBAAECggEAR3qRjRn60kRJil8L+2rikBZ/pP+ZIYDDS/KfkIQldp/75K2xAvgEC+Ryf/AZfu9fiLePQ2PlKcJMxILff62lds9kearj54miDhh+uGZvuFpXtYa8Jk7JOXnDGbBzlaGU/sF8dR9/sndCvAf5V2yd0ug9exA+62Y/7JLN7b020H3Y7cLTIM0Lbn/cDt/3Lg1NkCINpsYcqiMEjNYux3+o6EjRBkFrVz8oBzNYZad2tE90B3MP6QNmwiH3yyaACfwYG/g8A+d6mGrlYxl0Qpj7bhsZ3KpLlOj/qlqg81Vro+qsFy5F7eWPPA01e+usm8awQV7vgCOVzkZW7jtwMrMVXQKBgQDSSkk0VRKKCqGRRWEPmWlzN7Go6qSSF92XcVkH+82YGk6k83wu1odK3A4I24qdvpB9ckg8Zl9TGRCBYhe+3pN+U6RwgS6O71BXZnz3x907jNWcjgAmBbrHKbNTLGy5+HvXA71VJgexGMCW4tBzJo8sLpOPAXRHIsGhDGLjOmAThwKBgQDL+6pCcjJcJ9ywYNuPma5va2sGuzhRxUwY+jNCxDtOJQlzUsqxJxONS83GmfN4Ok2bhZMBMt2tIfePX9E96EWZ9JSE0FC4D4rRRnruOwTOh+8gFsvlN94Q+Oa58nuui8VQSNcGMS29tVXU3JQNgNbq7/CldqLhxuTdrlzxClxUEwKBgF9v5V9ByMMrZf4XHaDFwCzRNujxbLT87c1gXMaZycnhDpYgBtj+9bHMwvXUJUnIBa1ZI11+HH8LHgmKKjquqwOnFDcW+blW9QBlfAu8AjSXiw6dB4Y6DXV8AG2b+NBB7Ho9sTymoNEH6cfQskfAVTP5A3DgeRQbuwLLK0ny4U2bAoGAS5MFRLL8l4opSKvKDQ0aRKuerpLEzf70L7jbLxx3AH/WXYTKFhJtOwdfyPoW629me31ktqf6239fMh6E7pPU3bJxKDfqABe6Dck4GHWDVWWlodTwXA9z1gPxr+j4C/Y694DVMbUcxlGd6EyFCe+3MLoPBa7LsCy5dKx6QM/e30MCgYA4STQOJEEKFNGd0cJdeHrt3JACYMT8yexulAU/wmBI4n9GH8HloeOfuYLPU4/0USUcap7r6DOvnb3gwJL8tdGG6KvRQtynuEEc0LqfRtiZneflkWUR3yLa5L3dzt3lPLlNnyHEPVkAFvzD5E3lrxOaei3MpNJv9DkeG/La2BV1Pw==";		// APP_ID
	private final String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp4+ivi9XL28QAM+p8pDJ/gN1eDIprI+pPEwuXN3omhsb9k7kp4H95KAVuUcGaQBOdRJzdYonz6WEIfNYYOQEi8dwuOQFjZImXXE252fsSIFL2HbopnaKi+1AfLaQYxarSty6wHWxNqqauiX6JwISXUqRf0BPE266eqLZ692AdbJ15ZTTgdDDndVQ/nIUmcGF2qUvtLHkqbBbakN7V845v7Zi7nmn0ays5tRhZI0K2CtuSp4TYHDWDK+Sgxio+iDEVQI6K6WhjnfzdvpKrtMdJYoo52M6FtwD+1I+16uf2IdLq0ihTROUtguqmha4KHo6BqMNrlrrptC6h4dmJg2/BQIDAQAB";
	public static final String BASE_URL = "http://test2.artup.com/artup-mobile/";

	@Override
	public ResponseResult findWeChatPayResult(HttpServletRequest request) {
		long startTime = System.currentTimeMillis();
		LOGGER.info("PayServiceImpl-findWeChatPayResult-startTime=" + startTime);
		
		String return_code = request.getParameter("return_code");
		String return_msg = request.getParameter("return_msg");
		
		LOGGER.info("return_code = " + return_code + ", return_msg = " + return_msg);

		ResponseResult response = new ResponseResult();
		
		if("SUCCESS".equals(return_code)){
			String result_code = request.getParameter("result_code");
			
			if("SUCCESS".equals(result_code)){
				String transaction_id = request.getParameter("transaction_id");		// 微信支付订单号
				String out_trade_no = request.getParameter("out_trade_no");		// 商户订单号
				String appid = request.getParameter("appid");		// 公众账号ID

				Order order = new Order();
				order.setCode(out_trade_no);
				order.setStatus((byte) 2);
				order.setTransactionCode(transaction_id);
				
				try {
//					this.orderDao.updateOrder4StatusByCode(order);

					response.setStatus(Constants.ACTION_STATUS_SUCCESS);
					response.setMessage("支付成功。");
					LOGGER.info("支付成功。");
				} catch (Exception e) {
					response.setStatus(Constants.ACTION_STATUS_FAILURE);
					response.setMessage("支付失败！");
					LOGGER.error("支付失败！异常：", e);
				}
			} else {
				response.setStatus(Constants.ACTION_STATUS_FAILURE);
				response.setMessage("支付失败！");
			}
		} else {
			response.setStatus(Constants.ACTION_STATUS_FAILURE);
			response.setMessage("通信错误。");
		}
		
		response.setStatus(Constants.ACTION_STATUS_SUCCESS);
		response.setMessage("支付成功。");
		
		LOGGER.info("PayServiceImpl-findWeChatPayResult-耗时=" + (System.currentTimeMillis() - startTime));
		return response;
	}

	@Override
	public ResponseResult findWeChatPayResult(Map<String, Object> payNoticeMap) {
		long startTime = System.currentTimeMillis();
		LOGGER.info("PayServiceImpl-findWeChatPayResult-startTime=" + startTime);
		LOGGER.info("payNoticeMap = " + JSONObject.toJSONString(payNoticeMap));
		
		String returnCode = (String) payNoticeMap.get("return_code");
		String resultCode = (String) payNoticeMap.get("result_code");
		
		ResponseResult response = new ResponseResult();
		if("SUCCESS".equals(returnCode)){
			response.setStatus(Constants.ACTION_STATUS_SUCCESS);
			response.setMessage("[微信支付二次验证]网络畅通。");

			if("SUCCESS".equals(resultCode)){
				response.setStatus(Constants.ACTION_STATUS_SUCCESS);
				response.setMessage("[微信支付二次验证]支付成功。");
				
				String out_trade_no = (String) payNoticeMap.get("out_trade_no");
				String transaction_id = (String) payNoticeMap.get("transaction_id");
				String appid = (String) payNoticeMap.get("appid");
				
				Order order = new Order();
				order.setCode(out_trade_no);
				order.setStatus((byte) 2);
				order.setTransactionCode(transaction_id);
				
				try {
//					this.orderDao.updateOrder4StatusByCode(order);

					response.setStatus(Constants.ACTION_STATUS_SUCCESS);
					response.setMessage("[微信支付]成功。");
					LOGGER.info("[微信支付]成功。");
				} catch (Exception e) {
					response.setStatus(Constants.ACTION_STATUS_FAILURE);
					response.setMessage("[微信支付]失败！");
					LOGGER.error("[微信支付]失败！异常：", e);
				}
			} else {
				response.setStatus(Constants.ACTION_STATUS_FAILURE);
				response.setMessage("[微信支付二次验证]支付失败。");
			}
		} else {
			response.setStatus(Constants.ACTION_STATUS_FAILURE);
			response.setMessage("[微信支付二次验证]网络超时。");
		}
		
		LOGGER.info("PayServiceImpl-findWeChatPayResult-耗时=" + (System.currentTimeMillis() - startTime));
		return response;
	}
	
	@Override
	public ResponseResult findAliPayResult(Map<String, Object> payNoticeMap) {
		long startTime = System.currentTimeMillis();
		LOGGER.info("PayServiceImpl-findWeChatPayResult-startTime=" + startTime);
		LOGGER.info("payNoticeMap = " + JSONObject.toJSONString(payNoticeMap));
		
		String trade_status = (String) payNoticeMap.get("trade_status");
		
		ResponseResult esponseResult = new ResponseResult();
		
		if("TRADE_SUCCESS".equals(trade_status)){
			esponseResult.setStatus(Constants.ACTION_STATUS_SUCCESS);
			esponseResult.setMessage("[支付宝支付二次验证]交易成功。");

			String out_trade_no = (String) payNoticeMap.get("out_trade_no");

			Order order = new Order();
			order.setCode(out_trade_no);
			order.setStatus((byte) 2);
			
			try {
//				this.orderDao.updateOrder4StatusByCode(order);
				
				esponseResult.setStatus(Constants.ACTION_STATUS_SUCCESS);
				esponseResult.setMessage("[支付宝支付二次验证]成功。");
				LOGGER.info("[支付宝支付二次验证]成功。");
			} catch (Exception e) {
				esponseResult.setStatus(Constants.ACTION_STATUS_FAILURE);
				esponseResult.setMessage("[支付宝支付二次验证]失败！");
				LOGGER.error("[支付宝支付二次验证]失败！异常：", e);
			}
		} else {
			esponseResult.setStatus(Constants.ACTION_STATUS_FAILURE);
			esponseResult.setMessage("[支付宝支付二次验证]交易失败！");
		}
		
		LOGGER.info("PayServiceImpl-findWeChatPayResult-耗时=" + (System.currentTimeMillis() - startTime));
		return esponseResult;
	}
	
	/**
	 * create the order info. 创建订单信息
	 * 
	 */
	private String getOrderInfo(String subject, String body, String price, String orderCode) {

		// 签约合作者身份ID
		String orderInfo = "partner=" + "\"" + PARTNER_ID + "\"";

		// 签约卖家支付宝账号
		orderInfo += "&seller_id=" + "\"" + SELLER_ID + "\"";

		// 商户网站唯一订单号
		orderInfo += "&out_trade_no=" + "\"" + orderCode + "\"";

		// 商品名称
		orderInfo += "&subject=" + "\"" + subject + "\"";

		// 商品详情
		orderInfo += "&body=" + "\"" + body + "\"";

		// 商品金额
		orderInfo += "&total_fee=" + "\"" + price + "\"";

		// 服务器异步通知页面路径
		orderInfo += "&notify_url=" + "\"" + BASE_URL + "/admin/pay/queryAliMobilePayCallback" + "\"";

		// 服务接口名称， 固定值
		orderInfo += "&service=\"mobile.securitypay.pay\"";

		// 支付类型， 固定值
		orderInfo += "&payment_type=\"1\"";

		// 参数编码， 固定值
		orderInfo += "&_input_charset=\"utf-8\"";

		// 设置未付款交易的超时时间
		// 默认30分钟，一旦超时，该笔交易就会自动被关闭。
		// 取值范围：1m～15d。
		// m-分钟，h-小时，d-天，1c-当天（无论交易何时创建，都在0点关闭）。
		// 该参数数值不接受小数点，如1.5h，可转换为90m。
		orderInfo += "&it_b_pay=\"30m\"";

		// extern_token为经过快登授权获取到的alipay_open_id,带上此参数用户将使用授权的账户进行支付
		// orderInfo += "&extern_token=" + "\"" + extern_token + "\"";

		// 支付宝处理完请求后，当前页面跳转到商户指定页面的路径，可空
		orderInfo += "&return_url=\"" + BASE_URL + "\"";

		// 调用银行卡支付，需配置此参数，参与签名， 固定值 （需要签约《无线银行卡快捷支付》才能使用）
		// orderInfo += "&paymethod=\"expressGateway\"";

		return orderInfo;
	}
	
	/**
	 * get the out_trade_no for an order. 生成商户订单号，该值在商户端应保持唯一（可自定义格式规范）
	 * 
	 */
	private String getOutTradeNo() {
		SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss", Locale.getDefault());
		Date date = new Date();
		String key = format.format(date);

		Random random = new Random();
		key = key + random.nextInt();
		key = key.substring(0, 15);
		
		return key;
	}
	
}
